﻿using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace SH.Common.Helper
{
    public class JwtTokenHelper
    {

        private readonly IConfiguration _configuration;
        private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;
        public JwtTokenHelper(IConfiguration configuration, JwtSecurityTokenHandler jwtSecurityTokenHandler)
        {
            _configuration = configuration;
            _jwtSecurityTokenHandler = jwtSecurityTokenHandler;
        }
        /// <summary>
        /// 创建加密JwtToken
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public string CreateJwtToken<T>(T user, string? tenantId)
        {
            var signingAlogorithm = SecurityAlgorithms.HmacSha256;
            //CreateClaimList  将用户信息 加载到 载荷 当中
            var claimList = new List<Claim>() {
            new Claim( "https://schemas.microsoft.com/identity/claims/tenantid",tenantId ?? string.Empty),
            //new Claim( "UId",uId??string.Empty),
            };
            //Signature
            //取出私钥并以utf8编码字节输出
            var secretByte = Encoding.UTF8.GetBytes(_configuration["Auth:SecretKey"]);
            //使用非对称算法对私钥进行加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            //使用HmacSha256来验证加密后的私钥生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, signingAlogorithm);
            //生成Token
            var Token = new JwtSecurityToken(
            issuer: _configuration["Auth:Issuer"], //发布者
            audience: _configuration["Auth:Audience"], //接收者
            claims: claimList, //存放的用户信息
            notBefore: DateTime.UtcNow, //发布时间
            expires: DateTime.UtcNow.AddDays(1), //有效期设置为1天
            signingCredentials //数字签名
            );
            //生成字符串token
            var TokenStr = new JwtSecurityTokenHandler().WriteToken(Token);
            return TokenStr;
        }

        public T GetToken<T>(string Token)
        {
            Type t = typeof(T);
            //Activator.CreateInstance  根据 t(你传过来的泛型) 用反射的方式 new 当前对象 
            object objA = Activator.CreateInstance(t);
            var b = _jwtSecurityTokenHandler.ReadJwtToken(Token);
            foreach (var item in b.Claims)
            {
                PropertyInfo _Property = t.GetProperty(item.Type);
                if (_Property != null && _Property.CanRead)
                {
                    _Property.SetValue(objA, item.Value, null);
                }

            }
            return (T)objA;
        }

    }

}
